const std = @import("std");
const testing = std.testing;
const Regex = @import("regex").Regex;
const json = std.json;

pub fn load_json_from_file(file_path: []const u8) !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    var file = try std.fs.cwd().openFile(file_path, .{});

    defer _ = gpa.deinit();
    const allocator = gpa.allocator();
    // var buffer: [std.fs.max_path_bytes]u8 = undefined;

    const file_size = try file.getEndPos();
    const buffer = try allocator.alloc(u8, file_size);

    defer file.close();

    const bytes = try file.readAll(buffer);
    std.debug.assert(bytes == file_size);

    defer allocator.free(buffer);
    const json_str = try fixed_dirty_json_with_allocator(allocator, buffer);
    try save_content_to_file(json_str, file_path);
}
pub fn save_content_to_file(content: []const u8, file_path: []const u8) !void {
    const output = "fixed_json";
    _ = file_path;
    var file = try std.fs.cwd().createFile(output, .{});
    defer file.close();

    try file.writeAll(content);
}

pub fn fix_json(json_str: []const u8, allocator: std.mem.Allocator) ![]const u8 {
    const pattern =
        \\(?:
        \\    # 修复缺少逗号
        \\    (?<missing_comma>"[^"]+"\s*:\s*"[^"]+")(\s*"[^"]+"\s*:)
        \\    |
        \\    # 修复未引用的键
        \\    (?<unquoted_key>\s*)([a-zA-Z_][a-zA-Z0-9_]*)(\s*:)
        \\    |
        \\    # 修复单引号
        \\    (?<single_quote>'([^']+)')
        \\)
    ;

    var regex = try Regex.compile(allocator, pattern);

    var fixed_str = try allocator.dupe(u8, json_str);
    defer allocator.free(fixed_str);

    // 修复缺少逗号
    fixed_str = try regex.replaceAll(allocator, fixed_str, "(\"[^\"]+\"\\s*:\\s*\"[^\"]+\")(\\s*\"[^\"]+\"\\s*:)", "$1,$2");

    // 修复未闭合的括号
    if (!std.mem.endsWith(u8, fixed_str, "}")) {
        fixed_str = try std.fmt.allocPrint(allocator, "{s}}}", .{fixed_str});
    }

    // 修复未引用的键
    fixed_str = try regex.replaceAll(allocator, fixed_str, "(\\s*)([a-zA-Z_][a-zA-Z0-9_]*)(\\s*:)", "$1\"$2\"$3");

    // 修复单引号
    fixed_str = try regex.replaceAll(allocator, fixed_str, "'([^']+)'", "\"$1\"");

    // 修复无效的数字
    fixed_str = try regex.replaceAll(allocator, fixed_str, "(\\d+)[^\\d\\s,}]", "$1");

    return fixed_str;
}

pub fn fixed_dirty_json_with_allocator(allocator: std.mem.Allocator, json_str: []const u8) ![]const u8 {
    const fixed_str = try fix_json(json_str, allocator);
    // 解析 JSON 字符串
    const parsed = try json.parseFromSlice(json.Value, allocator, fixed_str, .{});

    defer allocator.free(fixed_str);
    var buffer = std.ArrayList(u8).init(allocator);

    defer buffer.deinit();
    try json.stringify(parsed.value, .{}, buffer.writer());
    std.log.info("Fixed JSON: {s}", .{buffer.items});
    return buffer.items;
}

pub fn fixed_dirty_json(json_str: []const u8) !void {
    // 分配一个内存分配器
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    // 解析 JSON 字符串
    const parsed = try json.parseFromSlice(json.Value, allocator, json_str, .{});

    var buffer = std.ArrayList(u8).init(allocator);

    defer buffer.deinit();

    try json.stringify(parsed.value, .{}, buffer.writer());
    std.log.info("Fixed JSON: {s}", .{buffer.items});
}

fn printJsonValue(writer: anytype, value: json.Value, indent: usize) !void {
    switch (value) {
        .object => |obj| {
            try writer.writeAll("{\n");
            var it = obj.iterator();
            var first = true;
            while (it.next()) |entry| {
                if (!first) {
                    try writer.writeAll(",\n");
                }
                first = false;
                try writer.writeByteNTimes(' ', indent + 2);
                try writer.print("\"{s}\": ", .{entry.key_ptr.*});
                try printJsonValue(writer, entry.value_ptr.*, indent + 2);
            }
            try writer.writeByte('\n');
            try writer.writeByteNTimes(' ', indent);
            try writer.writeByte('}');
        },
        .array => |arr| {
            try writer.writeAll("[\n");
            var i: usize = 0; // 手动维护索引
            for (arr.items) |item| {
                if (i > 0) {
                    try writer.writeAll(",\n");
                }
                try writer.writeByteNTimes(' ', indent + 2);
                try printJsonValue(writer, item, indent + 2);
                i += 1; // 更新索引
            }
            try writer.writeByte('\n');
            try writer.writeByteNTimes(' ', indent);
            try writer.writeByte(']');
        },
        .string => |s| try writer.print("\"{s}\"", .{s}),
        .integer => |n| try writer.print("{}", .{n}),
        .float => |f| try writer.print("{}", .{f}),
        .bool => |b| try writer.print("{}", .{b}),
        .null => try writer.writeAll("null"),
    }
}

test "load_json_from_file" {
    const path = "dirty_json";
    const buffer = try load_json_from_file(path) catch |err| {
        std.log.err("Error: {}", .{err});
        return error.FileNotFound;
    };
    std.log.info("File contents: {}", .{buffer[0..]});
}
